package com.hcc.export.helper.core.config;

import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.hcc.export.helper.core.exception.ExportException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.scheduling.annotation.EnableScheduling;

import javax.sql.DataSource;
import java.util.Optional;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@Configuration
@EnableScheduling
@ComponentScan("com.hcc.export.helper.core")
public class ExportHelperConfig {

    private final Environment environment;

    public ExportHelperConfig(Environment environment) {
        this.environment = environment;
    }

    @Bean
    public JdbcTemplate exportHelperJdbcTemplate(ObjectProvider<DataSource> dataSourceProvider) {
        DataSource dataSource = dataSourceProvider.getIfAvailable();
        if (dataSource == null) {
            throw new ExportException("未获取到数据源");
        }

        return new JdbcTemplate(dataSource);
    }

    @Bean("exportHelperExecuteService")
    public ExecutorService executorService() {
        int exportThreadNum = Optional.ofNullable(environment.getProperty("export.helper.exportThreadNum", Integer.class))
                .orElse(100);
        Integer exportThreadQueueNum = Optional.ofNullable(environment.getProperty("export.helper.exportThreadQueueNum", Integer.class))
                .orElse(10);

        ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("export-helper-%d").build();
        return new ThreadPoolExecutor(exportThreadNum, exportThreadNum, 0L, TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(exportThreadQueueNum),
                threadFactory,
                new ExportTaskRejectHandler());
    }

    @Slf4j
    public static class ExportTaskRejectHandler implements RejectedExecutionHandler {
        @Override
        public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
            throw new ExportException("当前实例导出繁忙，请稍后再试");
        }

    }

}
